package system

import (
	"MoSkeleton/framework/core/models"
	"MoSkeleton/models/base"
	"database/sql"
)

type SysMenu struct {
	models.MoModel
	MenuName  string         `gorm:"column:menu_name;type:VARCHAR(50);NOT NULL"  json:"menuName"`
	ParentId  uint64         `gorm:"column:parent_id;type:BIGINT;" json:"parentId"`
	OrderNum  int            `gorm:"column:order_num;type:INT;" json:"orderNum"`
	Path      string         `gorm:"column:path;type:VARCHAR(200);" json:"path"`
	Component string         `gorm:"column:component;type:VARCHAR(255);" json:"component"`
	Query     string         `gorm:"column:query;type:VARCHAR(255);" json:"query"`
	RouteName string         `gorm:"column:route_name;type:VARCHAR(50);" json:"routeName"`
	IsFrame   int            `gorm:"column:is_frame;type:INT;" json:"isFrame,string"`
	IsCache   int            `gorm:"column:is_cache;type:INT;" json:"isCache,string"`
	MenuType  string         `gorm:"column:menu_type;type:CHAR(1);" json:"menuType"`
	Visible   string         `gorm:"column:visible;type:CHAR(1);" json:"visible"`
	Status    string         `gorm:"column:status;type:CHAR(1);" json:"status"`
	Perms     string         `gorm:"column:perms;type:VARCHAR(100);"  json:"perms"`
	Icon      string         `gorm:"column:icon;type:VARCHAR(100);" json:"icon"`
	CreatedBy string         `gorm:"column:created_by;type:VARCHAR(32);" json:"createdBy"`
	UpdatedBy string         `gorm:"column:updated_by;type:VARCHAR(32);" json:"updatedBy"`
	Remark    sql.NullString `gorm:"column:remark;type:VARCHAR(500);" json:"remark"`
}

func (b *SysMenu) TableName() string {
	return "sys_menu"
}

func (b *SysMenu) HasChildrenMenu() (bool, error) {
	var count int64
	err := base.BaseDb.Model(b).Where("parent_id = ?", b.ID).Count(&count).Error
	return count > 0, err
}

/*
			select m.id
			from sys_menu m
	            left join sys_role_menu rm on m.id = rm.menu_id
	        where rm.role_id = #{roleId}
	            <if test="menuCheckStrictly">
	              and m.id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.id = rm.menu_id and rm.role_id = #{roleId})
	            </if>
			order by m.parent_id, m.order_num
*/
func (b *SysMenu) GetMenuListByRoleId(roleId uint64, menuCheckStrictly bool) ([]string, error) {
	db := base.GetModelDB(nil).Table("sys_menu m").Select("m.id")
	db.Joins("left join sys_role_menu rm on m.id = rm.menu_id").Where("rm.role_id = ?", roleId)
	if menuCheckStrictly {
		db.Where("m.id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.id = rm.menu_id and rm.role_id = ?)", roleId)
	}
	db.Order("m.parent_id, m.order_num")
	menuIds := make([]string, 0)
	err := db.Find(&menuIds).Error
	return menuIds, err
}
